package com.uduemc.biso.web.api.server.impl;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.extities.center.CustomerUser;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.extities.center.HostSetup;
import com.uduemc.biso.core.extities.center.Site;
import com.uduemc.biso.core.extities.center.custom.CustomerUserRole;
import com.uduemc.biso.core.extities.node.custom.LoginNode;
import com.uduemc.biso.core.extities.pojo.NodeTokenForCenter;
import com.uduemc.biso.core.extities.pojo.Relogin;
import com.uduemc.biso.core.feign.CustomerFeign;
import com.uduemc.biso.core.feign.HostFeign;
import com.uduemc.biso.core.feign.HostSetupFeign;
import com.uduemc.biso.core.feign.SiteFeign;
import com.uduemc.biso.core.utils.AESForJS;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.web.api.server.LoginNodeService;
import com.uduemc.biso.web.component.NodeFunction;

@Service
public class LoginNodeServiceImpl implements LoginNodeService {

	private static final Logger logger = LoggerFactory.getLogger(LoginNodeServiceImpl.class);

	@Autowired
	private NodeFunction nodeFunction;

	@Autowired
	private HostFeign hostFeign;

	@Autowired
	private CustomerFeign customerFeign;

	@Autowired
	private HostSetupFeign hostSetupFeign;

	@Autowired
	private SiteFeign siteFeign;

	@Autowired
	private ObjectMapper objectMapper;

	@Value("${spring.profiles.active}")
	private String active;

	@Override
	public LoginNode loginToken(String token) {
		NodeTokenForCenter nodeTokenForCenter = null;
		if (StringUtils.trimAllWhitespace(this.active).equals("dev")) {
			logger.info("通过开发模式不用从 redis 中获取数据直接构造数据返回！");
			try {
				Long id = Long.valueOf(token);
				if (id > 0) {
					nodeTokenForCenter = new NodeTokenForCenter(id, id, "customerUser");
				}
			} catch (NumberFormatException e) {
				if (token.equals("error")) {
					return null;
				}
			}
		}

		if (null == nodeTokenForCenter) {
			nodeTokenForCenter = nodeFunction.getNodeTokenForCenter(token);
		}

		if (nodeTokenForCenter == null) {
			logger.info("nodeTokenForCenter is empty");
			return null;
		}

		LoginNode loginNode = getLoginNodeByNodeTokenForCenter(nodeTokenForCenter);

		if (null == loginNode) {
			logger.info("loginNode is empty");
			return null;
		}

		return loginNode;
	}

	@Override
	public LoginNode reLoginToken(String relogintoken) {

		if (!StringUtils.hasText(relogintoken)) {
			logger.info("relogintoken is empty");
			return null;
		}

		NodeTokenForCenter nodeTokenForCenter = null;
		try {
			String jsonString = AESForJS.de(relogintoken);
			Relogin relogin = objectMapper.readValue(jsonString, Relogin.class);
			logger.info("重新登录解密获取的 relogin：" + relogin.toString());
			if (null == relogin || relogin.getUntime() == null || relogin.getNodeTokenForCenter() == null) {
				logger.info("relogin is empty");
				return null;
			}
			LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0);
			LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59);
			LocalDateTime atTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(relogin.getUntime()),
					ZoneId.systemDefault());
			if (atTime.isBefore(startTime) || atTime.isAfter(endTime)) {
				logger.info("atTime is before or after now :"
						+ atTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
				return null;
			}

			nodeTokenForCenter = relogin.getNodeTokenForCenter();

		} catch (Exception e) {
			e.printStackTrace();
		}

		if (nodeTokenForCenter == null) {
			logger.info("nodeTokenForCenter is empty");
			return null;
		}

		LoginNode loginNode = getLoginNodeByNodeTokenForCenter(nodeTokenForCenter);

		if (null == loginNode) {
			logger.info("loginNode is empty");
			return null;
		}
		return loginNode;
	}

	@SuppressWarnings("unchecked")
	@Override
	public LoginNode getLoginNodeByNodeTokenForCenter(NodeTokenForCenter nodeTokenForCenter) {
		LoginNode loginNode = new LoginNode();

		// host 的信息
		Long hostId = nodeTokenForCenter.getHostId();
		RestResult restResult = hostFeign.findOne(hostId);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			logger.info("hostFeign.findOne(hostId); hostId: " + hostId
					+ " restResult.getCode() != 200 || restResult.getData() == null");
			return null;
		}
		Host host = null;
		try {
			host = objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()), Host.class);
		} catch (Exception e2) {
			e2.printStackTrace();
		}
		if (host == null) {
			logger.info("获取 host 数据失败，hostId: " + hostId);
			return null;
		}
		logger.info("获取host的数据: " + host.toString());
		loginNode.setHost(host);

		// host 的用户信息
		Long customerUserId = host.getUserId();
		restResult = customerFeign.findUserOne(customerUserId);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			logger.info("customerFeign.findOne(customerUserId); customerUserId: " + customerUserId
					+ " restResult.getCode() != 200 || restResult.getData() == null");
			return null;
		}
		CustomerUser customerUser = null;
		try {
			customerUser = objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()),
					CustomerUser.class);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		if (customerUser == null) {
			logger.info("获取 customerUser 数据失败，customerUserId: " + customerUserId);
			return null;
		}
		logger.info("获取 customerUser 的数据: " + customerUser.toString());
		customerUser.setPasswordHash("");
		loginNode.setCustomerUser(customerUser);

		// 登录的用户信息
		if ("customerUser".equals(nodeTokenForCenter.getUserType())) {

			loginNode.setLoginUserType(nodeTokenForCenter.getUserType());
			loginNode.setLoginUserId(customerUser.getId());
			loginNode.setLoginUserName(
					StringUtils.hasText(customerUser.getName()) ? customerUser.getName() : "Undefined");

			// 获取权限
			restResult = customerFeign.findRoleById(customerUser.getId());
			JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class,
					CustomerUserRole.class);
			List<CustomerUserRole> customerUserRole = null;
			try {
				customerUserRole = (List<CustomerUserRole>) objectMapper
						.readValue(objectMapper.writeValueAsString(restResult.getData()), javaType);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (CollectionUtils.isEmpty(customerUserRole)) {
				customerUserRole = new ArrayList<>();
			}
			customerUserRole.add(0, new CustomerUserRole(0L, 0L, "访客", "guest"));
			loginNode.setRoles(customerUserRole);
		}

		// hostSetup 信息
		restResult = hostSetupFeign.findInfoByHostId(hostId);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			logger.info("hostSetupFeign.findInfoByHostId(hostId); hostId: " + hostId
					+ " restResult.getCode() != 200 || restResult.getData() == null");
			return null;
		}
		HostSetup hostSetup = null;
		try {
			hostSetup = objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()), HostSetup.class);
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		if (null != hostSetup && hostSetup.getId().longValue() > 0) {
			loginNode.setHostSetup(hostSetup);
		}

		// 站点信息
		restResult = siteFeign.findByHostId(hostId);
		if (restResult.getCode() != 200 || restResult.getData() == null) {
			logger.info("siteFeign.findByHostId(hostId); hostId: " + hostId
					+ " restResult.getCode() != 200 || restResult.getData() == null");
			return null;
		}
		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Site.class);
		List<Site> sites = null;
		try {
			sites = (List<Site>) objectMapper.readValue(objectMapper.writeValueAsString(restResult.getData()),
					javaType);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		if (!CollectionUtils.isEmpty(sites)) {
			loginNode.setSites(sites);
		}

		// 重新登录的token
		String reloginToken = null;
		try {
			Relogin relogin = new Relogin(nodeTokenForCenter, new Date().getTime());
			String jsonString = objectMapper.writeValueAsString(relogin);
			logger.info("重新登录的明文：" + jsonString);
			reloginToken = AESForJS.en(jsonString);
		} catch (Exception e) {
			e.printStackTrace();
		}

		logger.info("重新登录的token：" + reloginToken);
		loginNode.setReloginToken(reloginToken);

		// 创建时间
		loginNode.setCreateAt(new Date());
		return loginNode;
	}

}
